package com.quick.develop.form.utils;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.quick.develop.form.vo.ImportResultVO;
import com.quick.develop.framework.common.exception.ServerException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;

@Slf4j
public class ExcelUtils {

    public static <T> void downloadExcel(Class<T> tClass, List<T> dataList, String fileName) {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
        if (Objects.isNull(servletRequestAttributes)) {
            throw new ServerException("系统异常，导出失败!");
        }
        try {
            HttpServletResponse response = servletRequestAttributes.getResponse();
            if (Objects.isNull(response)) {
                throw new ServerException("系统异常，导出失败!");
            }
            // 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            fileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            EasyExcel.write(response.getOutputStream(), tClass).sheet("模板").doWrite(dataList);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    public static <T> void execWriteDatabase(
            MultipartFile file,
            Class<T> tClass,
            DynamicImport<T> filter,
            DynamicImport<T> overwrite,
            Consumer<List<T>> overwriteConsumer,
            Consumer<List<T>> insertConsumer) {
        try {
            List<T> dataList = new ArrayList<>();
            ImportResultVO resultVO = new ImportResultVO();
            EasyExcel.read(file.getInputStream(), tClass, new ReadListener<T>() {
                @Override
                public void invoke(T data, AnalysisContext context) {
                    dataList.add(data);
                }
                @Override
                public void doAfterAllAnalysed(AnalysisContext context) {
                    // 解析完成后的操作
                    if (CollUtil.isNotEmpty(dataList)) {
                        resultVO.setTotal(dataList.size());
                        List<T> filterResult = dataList;
                        // 过滤无效的数据
                        if (Objects.nonNull(filter)) {
                            filterResult = filter.accept(filterResult);
                        }
                        resultVO.setFilter(resultVO.getTotal() - filterResult.size());
                        // 需要重写的数据
                        List<T> overwriteResult = new ArrayList<>();
                        if (Objects.nonNull(overwrite)) {
                            overwriteResult = overwrite.accept(overwriteResult);
                        }
                        Set<T> collect = new HashSet<>(overwriteResult);
                        dataList.removeIf(collect::contains);
                        resultVO.setOver(overwriteResult.size());
                        if (Objects.isNull(overwriteConsumer)) {
                            throw new IllegalArgumentException("overwriteConsumer不能为空");
                        }
                        overwriteConsumer.accept(overwriteResult);
                        if (Objects.isNull(insertConsumer)) {
                            throw new IllegalArgumentException("insertConsumer不能为空");
                        }
                        insertConsumer.accept(dataList);
                    }
                }
            });
        } catch (Exception e) {
            log.error("导入失败:{}", e.getMessage());
        }
    }
}
